import { getImportUrlSuffix } from '@fangzhongya/utils/urls/getImportUrlSuffix';
import { getUrlCatalogueLast } from '@fangzhongya/utils/urls/getUrlCatalogueLast';
import { lineToLargeHump } from '@fangzhongya/utils/name/lineToLargeHump';
import { resolve, join } from 'node:path';
import { defaultConfig as defaultConfigExport, FangExport } from '../export';
import { fsAccess } from '../common';
import { getSort } from '@fangzhongya/utils/basic/object/getSort';

import type { Config as ConfigExport, FileDatas } from '../export';
import type { RurDevCallback, ConfigCallback, FsReaddir } from '../com';

type Objstr = {
	[key: string]: string;
};

export interface Config extends ConfigExport {
	/**
	 * 公共方法dir后的路径
	 */
	utilurl?: string | ((a: string) => string);
	alias?: string;
	/**
	 * 替换头的完整路径
	 */
	dittop?: string;
	vue?: string;
	export?: string;
	function?: string;
	scss?: string;
	/**
	 * 拼接头
	 */
	splicetop?: string;

	libExport?: string;
	/**
	 * 文件地址
	 */
	liburl?: string;

	/**
	 * 总文件完成后
	 */
	dirLib: (arr: Objstr) => void;
	/**
	 * 分割线
	 */
	branch?: string;
	/**
	 *	是否生成index.scss文件
	 */
	isScssIndex?: boolean;
}

export const defaultConfig: Config = Object.assign({}, defaultConfigExport, {
	name: 'vue',
	/**
	 * 合并文件头
	 */
	utilurl: 'util.ts',
	alias: '',
	dir: './src/components/',
	extensions: ['vue', 'ts'],
	vue: 'src/index',
	scss: 'index.scss',
	scss2: 'index2.scss',
	gene: 'index.ts',
	matchexts: [/[\\|\/]src[\\|\/]index\.[vue|ts]$/],
	branch: '/',
	libExport: 'filter',
	dirLib(arr: Objstr) {},
	fileTop(_url: string, _files: FsReaddir) {
		return [] as string[];
	},
	fileDirs(_url: string, _files: FsReaddir, _name: string) {
		return [] as string[];
	},
	fileFile(_url: string, _files: FsReaddir, _name: string, _wjmc: string) {
		return [] as string[];
	},
	fileEnd(_url: string, _files: FsReaddir, _name: Array<string>) {
		return [] as string[];
	},
});

export class FangVueLib extends FangExport {
	_indexUrls: string[];
	_indexScss: string[];
	_indexScss2: string[];
	_libObj: Objstr;
	constructor(config?: Config, callback?: ConfigCallback) {
		super();
		this._indexUrls = [];
		this._indexScss = [];
		this._indexScss2 = [];
		this._libObj = {};
		this.config = {};
		this._configCallback = callback;
		defaultConfig.liburl = resolve(process.cwd(), 'build.lib.ts');
		defaultConfig.fileEnd = async (
			url: string,
			files: FsReaddir,
			arr?: Array<string> | string,
		) => {
			return await this.setFileEnd(url, files, arr as string[]);
		};
		this._defaultConfig = defaultConfig;
		this.initConfig(config || this.config);
	}
	async setFileEnd(url: string, files: FsReaddir, arr: Array<string>) {
		if (files.dirs.length > 0 && files.dirs.includes('src')) {
			const mlz = getUrlCatalogueLast(url);
			// const riu = getReplaceImportUrl(url, this.config.dittop);
			const key = url
				.replace(this.config.dittop, '')
				.substring(1)
				.replace(/[\\|\/]/g, this.config.branch);

			this._libObj[key] = join(this.config.splicetop, mlz).replace(
				/[\\|\/]/g,
				this.config.branch,
			);
			const zswj = join(url, this.config.gene);
			let iu;
			if (typeof this.config.utilurl == 'function') {
				iu = this.config.utilurl(zswj);
			} else {
				iu = getImportUrlSuffix(
					zswj,
					join(this.getDirUrl(), this.config.utilurl),
				);
			}
			const ins = getImportUrlSuffix(
				join(this.getDirUrl(), this.config.gene),
				zswj,
			);
			this._indexUrls.push(`export * from '${ins}';`);
			let alias = '';
			if (this.config.alias) {
				alias = this.config.alias + '-';
			}
			const name = lineToLargeHump(alias + mlz);
			// const mlzName = lineToLargeHump(mlz);
			const rarr = [];
			// const isc = await fsAccess(resolve(url, './src/index.css'));
			// if (isc) {
			// 	rarr.push(`import './src/index.css';`);
			// 	this._indexScss.push(
			// 		`@use '${ins.replace(/\/index$/, '')}/src/index.css' as *;`,
			// 	);
			// }
			// 生成样式列表
			const isscss2 = await fsAccess(
				resolve(url, './' + this.config.scss2),
			);
			if (isscss2) {
				this._indexScss2.push(
					`@use '${ins.replace(/\/index$/, '')}/${
						this.config.scss2
					}' as *;`,
				);
			}

			// 样式
			const isscss = await fsAccess(
				resolve(url, './' + this.config.scss),
			);
			if (isscss) {
				rarr.push(`import './${this.config.scss}';`);
				const as = `@use '${ins.replace(/\/index$/, '')}/${
					this.config.scss
				}' as *;`;
				if (!isscss2) {
					this._indexScss2.push(as);
				}
				this._indexScss.push(as);
			}

			// 判断文件类型
			const isv = await fsAccess(
				resolve(url, `./${this.config.vue}.vue`),
			);
			if (isv) {
				rarr.push(`import SrcVue from './${this.config.vue}.vue'`);
			} else {
				rarr.push(`import SrcVue from './${this.config.vue}'`);
			}
			// 导出
			if (this.config.export) {
				const ise =
					(await fsAccess(
						resolve(url, this.config.export + '.ts'),
					)) ||
					(await fsAccess(resolve(url, this.config.export + '.js')));
				if (ise) {
					rarr.push(`export * from '${this.config.export}';`);
				}
			}
			// 方法
			if (this.config.function) {
				const ise =
					(await fsAccess(
						resolve(url, this.config.function + '.ts'),
					)) ||
					(await fsAccess(
						resolve(url, this.config.function + '.js'),
					));

				if (ise) {
					rarr.push(
						`import { withInstall } from '${this.config.function}'`,
					);
				} else {
					rarr.push(`import { withInstall } from '${iu}'`);
				}
			} else {
				rarr.push(`import { withInstall } from '${iu}'`);
			}
			rarr.push(`const ${name} = withInstall(SrcVue, '${name}');`);

			rarr.push(`export { ${name} };`);
			// 本地无法使用引用
			// if (name !== mlzName) {
			// 	rarr.push(`   SrcVue as ${mlzName},`);
			// }
			rarr.push(`export default ${name};`);
			// const isd = await fsAccess(
			//     resolve(url, './src/data.ts'),
			// );
			// if (isd) {
			//     rarr.push(
			//         `export * as ${name}Data from './src/data';`,
			//     );
			// }
			return rarr;
		} else if (url == this.getDirUrl()) {
			if (this.config.issort) {
				this._indexUrls.sort();
				return this._indexUrls;
			} else {
				return this._indexUrls;
			}
		} else {
			if (arr instanceof Array) {
				arr.splice(0, arr.length);
			}
			return [];
		}
	}
	async runDev(
		callback?: RurDevCallback | undefined,
		configCallback?: ConfigCallback | undefined,
		config?: Config | undefined,
	) {
		const rarr = await super.runDev(callback, configCallback, config, true);

		const arr = [];
		if (/\.json$/.test(this.config.liburl)) {
		} else {
			arr.push(`export const ${this.config.libExport} = `);
		}
		if (this.config.issort) {
			this._libObj = getSort(this._libObj);
		}
		arr.push(JSON.stringify(this._libObj, null, 4));
		this.fileOpen(this.config.liburl, arr.join('\n'), [], 0);
		this.config.dirLib(this._libObj);

		setTimeout(() => {
			this.generateScss();
		});

		return rarr;
	}

	generateScss() {
		if (this._indexScss.length > 0) {
			if (this.config.issort) {
				this._indexScss.sort();
			}
			this.fileOpen(
				join(this.getDirUrl(), 'index.scss'),
				this._indexScss.join('\n'),
				[],
				0,
			);
		}

		if (this._indexScss2.length > 0) {
			if (this.config.issort) {
				this._indexScss2.sort();
			}
			this.fileOpen(
				join(this.getDirUrl(), 'index2.scss'),
				this._indexScss2.join('\n'),
				[],
				0,
			);
		}
	}
}
export function runDev(
	config?: Config,
	configCallback?: ConfigCallback,
	callback?: RurDevCallback,
) {
	const fang = new FangVueLib(config);
	fang.runDev(callback, configCallback);
}
